package com.yonyou.openapi.base.sso.sso;


import com.yonyou.openapi.base.sso.BaseOpenApi;
import com.yonyou.openapi.base.sso.pojo.ApiDataResponse;
import com.yonyou.openapi.base.sso.pojo.ThirdUserBo;
import com.yonyou.openapi.base.exception.BusinessException;
import com.yonyou.openapi.base.properties.OpenApiProperties;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;


/**
 * @description: 单点登录
 * @author: nishch
 * @create: 2021-07-07
 **/
@Component
public class SingleSignOn extends BaseOpenApi {

    //获取临时code
    private final static String sso_code = "/yonbip/yht/getThirdLoginCode";
    //单点登录拼接地址
    private final static String open_ys_url = "%s/cas/thirdOauth2CodeLogin?thirdUCId=%s&code=%s&service=%s";
    //三方系统自己拼接跳转地址
    private final static String open_url = "%s/cas/thirdOauth2CodeLogin?thirdUCId=%s&code=%s&service=";
    //不需要拼接跳转地址
    private final static String url = "%s/cas/thirdOauth2CodeLogin?thirdUCId=%s&code=%s";

    @Resource
    public OpenApiProperties properties;
    private ThirdUserBo thirdUserBo = new ThirdUserBo();

    public ThirdUserBo init(String userId) {
        thirdUserBo.setUserId(userId);
        thirdUserBo.setThirdUcId(properties.getThirdUcId());
        return thirdUserBo;
    }

    /**
     * 获取登录到控制台的地址
     *
     * @param entity 第三方用户信息
     * @return 最终实现单点的地址
     */
    public String getSSOUrlToIndex(ThirdUserBo entity) {
        String code = getCode(entity);
        String thirdUCId = entity.getThirdUcId();
        return String.format(open_ys_url, properties.getSsoYhtUrl(), thirdUCId, code, encode(getAccess_tet(), true));
    }

    /**
     * 获取登录到指定页面  --- 根据serviceCode跳转
     *
     * @param entity 第三方用户信息
     * @return 最终实现单点的地址
     */
    public String getSSOUrlToNode(ThirdUserBo entity) throws Exception {
        return getString(entity, String.format(getAccess_tet_node(), entity.getServiceCode()), false);
    }


    /**
     * 获取登录到指定页面 --- url只填写路径，域名信息取对应数据中心
     *
     * @param entity 第三方用户信息
     * @param url    要跳转的真实地址
     * @return 最终实现单点的地址
     */
    public String getSSOUrlToUrl(ThirdUserBo entity, String url) {
        return getString(entity, getBaseUrl() + url, false);
    }


    /**
     * 获取登录到指定页面  ----完整地址
     *
     * @param entity 第三方用户信息
     * @param url    要跳转的真实地址
     * @return 最终实现单点的地址
     */
    public String getSSOUrlToUrl2(ThirdUserBo entity, String url) {
        return getString(entity, url, false);
    }


    /**
     * 待办被集成  ---- 用于待办被集成，拼接租户ID，避免跳转找不到数据.
     *
     * @param entity 第三方用户信息
     * @param url    要跳转的真实地址
     * @return 最终实现单点的地址
     */
    public String getSSOUrlToDO(ThirdUserBo entity, String url) {
        return getString(entity, url, true);
    }

    private String getString(ThirdUserBo entity, String url, boolean b) {
        entity.setThirdUcId(properties.getThirdUcId());
        String code = getCode(entity);
        String thirdUCId = properties.getThirdUcId();
        String node = encode(url, b);
        String nodeUrl = getAccess_tet() + "?tenantId=" + properties.getTenantId() + "&service=" + node;
        return String.format(open_ys_url, properties.getSsoYhtUrl(), thirdUCId, code, encode(nodeUrl, true));
    }

    /**
     * 单点至控制台
     *
     * @return String 目标路径
     */
    private String getAccess_tet() {
        return getBaseUrl() + "/login";
    }

    /**
     * 单点至指定节点
     *
     * @return String 目标路径
     */
    private String getAccess_tet_node() {
        return getBaseUrl() + "/?effect=headless#/service/%s";
    }


    /**
     * 获取免登code
     *
     * @param entity 第三方用户信息
     * @return code
     * @throws BusinessException 接口返回异常
     */
    private String getCode(ThirdUserBo entity) {
        if (null == entity || StringUtils.isBlank(entity.getThirdUcId()) || StringUtils.isBlank(entity.getUserId())) {
            throw new BusinessException("用户参数不全");
        }
        ApiDataResponse apiDataResponse = postForEntity(sso_code, entity, ApiDataResponse.class);
        return getData(apiDataResponse).get("code").toString();
    }

    private String encode(String url, boolean isNeedTenantId) {
        try {
            if (isNeedTenantId) {
                if (StringUtils.contains(url, "?")) {
                    return URLEncoder.encode(url + "&tenantId=" + properties.getTenantId(), StandardCharsets.UTF_8.toString());
                } else {
                    return URLEncoder.encode(url + "?tenantId=" + properties.getTenantId(), StandardCharsets.UTF_8.toString());
                }
            } else {
                return URLEncoder.encode(url, StandardCharsets.UTF_8.toString());
            }
        } catch (Exception e) {
            throw new BusinessException("url转义异常：" + url);
        }
    }

    /**
     * 获取基础域名
     *
     * @return 基础域名
     */
    private String getBaseUrl() {
        String businessUrl = dataCenterUrlProvider.buildBusinessUrl();
        return businessUrl.split("/iuap-api-gateway")[0];
    }

    /**
     * 获取单点登录地址时要跳转的地址前缀
     */
    public String getSSOUrl(String userId, String type) {
        ThirdUserBo entity = new ThirdUserBo();
        entity.setThirdUcId(properties.getThirdUcId());
        entity.setUserId(userId);
        String code = getCode(entity);
        String thirdUCId = properties.getThirdUcId();
        return String.format(open_url, properties.getSsoYhtUrl(), thirdUCId, code);
    }

}
